package sto.orz.rptp.webapp.action;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import sto.orz.html.form.Form;
import sto.orz.html.form.FormFactory;
import sto.orz.json.JSONAdapter;
import sto.orz.json.JSONDataset;
import sto.orz.json.JSONForm;
import sto.orz.json.JSONMessage;
import sto.orz.json.JSONUtil;
import sto.orz.rptp.model.Attribute;
import sto.orz.rptp.model.Dataset;
import sto.orz.rptp.model.Datasource;
import sto.orz.rptp.model.Definition;
import sto.orz.rptp.service.*;

import sto.orz.webapp.action.BaseAction;

public class DefinitionAction extends BaseAction implements JSONProvideAction {
	private static final long serialVersionUID = 3719328376033937816L;

	private DatasetManager datasetManager;

	private String definitionId;
	private String definitionName;

	private String datasetId;

	private JSONAdapter json;
	protected final Log log = LogFactory.getLog(getClass());
	private Definition rptd;
	private Dataset dataset;
	private DefinitionManager rptdManager;
	private FormManager formManager = null;

	public void setFormManager(FormManager formManager) {
		this.formManager = formManager;
	}

	public String doDataset() {
		Form form = FormFactory.getForm("dataset", Dataset.class);
		formManager.pickupData(form, dataset);
		json = JSONUtil.response("保存dataset.未完成!");
		return SUCCESS;
	}

	// 没指定datasetId
	public String doDatasetForm() {
		Form form = FormFactory.getForm("dataset", Dataset.class);

		if (datasetId != null) {
			dataset = datasetManager.get(datasetId);
		} else {
			dataset = new Dataset();
		}

		formManager.injectData(form, dataset);
		json = new JSONForm(form);
		return SUCCESS;
	}

	public String doData() {
		try {
			rptd = getDefinitionById();
			Dataset ds = (Dataset) rptd.getDatasets().toArray()[0];
			json = new JSONDataset(ds);
		} catch (Exception e) {
			json = JSONUtil.response("参数错误或数据库无此数据! definitionId = "
					+ definitionId);
		}
		if (log.isDebugEnabled()) {
			log.debug("Dataset [json format] : " + json.toJson());
		}
		return SUCCESS;
	}

	public String doDelete() {
		rptdManager.removeDefinition(definitionId);
		json = new JSONMessage("Delete OK");
		return SUCCESS;
	}

	// FIXME Formfactory json格式改变,造成js错误
	public String doEdit() {
		if (definitionId == null) {
			json = JSONUtil.response("没有指定要编辑的报表编号!");
			return SUCCESS;
		}

		rptd = rptdManager.getDefinition(definitionId);
		Form form = FormFactory.getForm("rptd", rptd);
		json = JSONUtil.jsonForm("rptd", this.rptd);
		return SUCCESS;
	}

	public Dataset getDataset() {
		return dataset;
	}

	public void setDataset(Dataset dataset) {
		this.dataset = dataset;
	}

	public String doInit() {
		rptd = initDemoData();
		definitionId = rptd.getId();
		json = JSONUtil.response("数据初始化完毕");
		if (log.isDebugEnabled()) {
			log.debug("Definition Init Complete [json format] : "
					+ json.toJson());
		}
		return SUCCESS;
	}

	// TODO 没有dataset时的错误处理
	// 4028807c0f6f1ce4010f6f1cf33c0004
	public String doJson() {
		try {
			rptd = getDefinitionById();
			Dataset ds = (Dataset) rptd.getDatasets().toArray()[0];
			json = JSONUtil.fromObject(rptd);
		} catch (Exception e) {
			json = JSONUtil.response("参数错误或数据库无此数据");
		}
		if (log.isDebugEnabled()) {
			log.debug("Definition [json format] : " + json.toJson());
		}
		return SUCCESS;
	}

	public String doList() {
		java.util.List d = rptdManager.getAll();
		json = JSONUtil.fromCollection(d);
		if (log.isDebugEnabled()) {
			log.debug("Definition List [json format] : " + json.toJson());
		}
		return SUCCESS;
	}

	public String doNew() {
		rptd = rptdManager.createNewReportDefinition(this.definitionName);
		json = JSONUtil.response(rptd.getId());
		return SUCCESS;
	}

	public String doSave() {
		rptdManager.saveDefinition(rptd);
		json = new JSONMessage("Save OK");
		return SUCCESS;
	}

	public String doAddDataset() {
		try {
			rptd = getDefinitionById();
			rptd.getDatasets().add(dataset);
			rptdManager.saveObject(dataset);
			rptdManager.saveDefinition(rptd);
			json = new JSONMessage("Save dataset OK");
		} catch (Exception e) {
			json = JSONUtil.response("参数错误或数据库无此数据");
		}
		if (log.isDebugEnabled()) {
			log.debug("Definition [json format] : " + json.toJson());
		}
		return SUCCESS;
	}

	// TODO 错误明确化
	// definitionId == null 错误
	// 数据库无记录错误
	private Definition getDefinitionById() throws Exception {
		Definition rpt;
		try {
			rpt = rptdManager.getDefinition(definitionId);
			if (rpt == null)
				throw new Exception();
			return rpt;
		} catch (Exception e) {
			throw new Exception();
		}

	}

	// TODO 错误明确化
	// definitionId == null 错误
	// 数据库无记录错误
	private Dataset getDatasetById() {
		Dataset ds;
		try {
			ds = datasetManager.get(datasetId);
			if (ds == null)
				throw new Exception();
		} catch (Exception e) {
			ds = new Dataset();
		}
		return ds;

	}

	public JSONAdapter getJson() {
		return json;
	}

	public Definition getRptd() {
		return rptd;
	}

	public String doInitData() {
		initDemoData();
		log.info("测试数据导入完毕!");
		return "index";
	}

	// TODO move to unit test class
	private Definition initDemoData() {
		// 构造对象
		Definition rptd = new Definition();
		rptd.setName("简单报表方案一 (Northwind:customers)");

		Attribute attr = new Attribute();
		attr.setName("Title");
		attr.setValue("Northwind Customer Profile");

		Attribute attr2 = new Attribute();
		attr2.setName("Description");
		attr2.setValue("演示最简单的报表");

		rptd.getAttributes().add(attr);
		rptd.getAttributes().add(attr2);

		Datasource datasource = new Datasource();
		datasource.setName("Northwind");
		datasource.setDriver("org.hsqldb.jdbcDriver");
		datasource.setUrl("jdbc:hsqldb:hsql://localhost/northwind");
		datasource.setUsername("sa");
		datasource.setPassword("");

		Dataset ds1 = new Dataset();
		ds1.setName("NorthWindDataset");
		ds1.setQuery("select top 10 * from customers");
		ds1.setDatasource(datasource);

		// Dataset ds2 = new Dataset();
		// ds2.setName("ds2");
		// ds2.setQuery("select * from item");
		// ds2.setDatasource(datasource);

		rptd.getDatasets().add(ds1);
		// rptd.getDatasets().add(ds2);

		rptdManager.saveObject(datasource);
		rptdManager.saveObject(ds1);
		// rptdManager.saveObject(ds2);

		rptdManager.saveDefinition(rptd);
		return rptd;
	}

	public void setDefinitionId(String definitionId) {
		this.definitionId = definitionId;
	}

	public void setDefinitionName(String definitionName) {
		this.definitionName = definitionName;
	}

	public void setRptd(Definition rptd) {
		this.rptd = rptd;
	}

	public void setRptdManager(DefinitionManager rptdManager) {
		this.rptdManager = rptdManager;
	}

	public void setDatasetId(String datasetId) {
		this.datasetId = datasetId;
	}
}
